package com.linqi.freebie.http.ktorClientCio.request

import com.linqi.freebie.http.ktorClientCio.response.ResponseHolder
import io.ktor.client.request.*
import io.ktor.client.request.forms.FormDataContent
import io.ktor.http.*
import kotlinx.serialization.serializer
/**
 * 基于 Ktor 的 HTTP 请求帮助类
 */
object HttpRequestHelper {

    /**
     * Http GET 请求
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> get(
        url: String,
        headers: Map<String, String>? = null,
        params: Map<String, String>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.get(url) {
                headers?.forEach { (k, v) -> header(k, v) }
                params?.forEach { (k, v) -> parameter(k, v) }
            }
        }
    }



    /**
     * Http POST (Form 表单方式)
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> postForm(
        url: String,
        headers: Map<String, String>? = null,
        params: Map<String, String>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        // 获取类型T的序列化器
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.post(url) {
                headers?.forEach { (k, v) -> header(k, v) }
                setBody(FormDataContent(Parameters.build {
                    params?.forEach { (k, v) -> append(k, v) }
                }))
            }
        }
    }


    @JvmOverloads
    suspend inline fun <reified T : Any> postJsonString(
        url: String,
        headers: Map<String, String>? = null,
        content: String? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        // 获取类型T的序列化器
        val serializer = serializer<T>()

        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.post(url) {
                // 添加请求头
                headers?.forEach { (k, v) -> header(k, v) }

                // 设置 Content-Type
                contentType(ContentType.Application.Json)
                // 设置 JSON 字符串体
                setBody(content ?: "{}")
            }
        }
    }



    /**
     * Http PUT
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> put(
        url: String,
        headers: Map<String, String>? = null,
        params: Map<String, @JvmSuppressWildcards Any>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.put(url) {
                headers?.forEach { (k, v) -> header(k, v) }
                params?.forEach { (k, v) ->
                    when (v) {
                        is String -> parameter(k, v)
                        else -> setBody(v) // 复杂对象直接作为 JSON body
                    }
                }
            }
        }
    }

    /**
     * Http DELETE
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> delete(
        url: String,
        headers: Map<String, String>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.delete(url) {
                headers?.forEach { (k, v) -> header(k, v) }
            }
        }
    }

    /**
     * Http HEAD
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> head(
        url: String,
        headers: Map<String, String>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.head(url) {
                headers?.forEach { (k, v) -> header(k, v) }
            }
        }
    }

    /**
     * Http OPTIONS
     */
    @JvmOverloads
    suspend inline fun <reified T : Any> options(
        url: String,
        headers: Map<String, String>? = null,
        isInfoResponse: Boolean = true
    ): ResponseHolder<T> {
        val serializer = serializer<T>()
        return RequestCore.request(serializer, isInfoResponse) { client ->
            client.options(url) {
                headers?.forEach { (k, v) -> header(k, v) }
            }
        }
    }
}
